package com.cj.sys.entity.security;

import java.util.LinkedHashSet;
import java.util.List;
import java.util.Set;

import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.FetchType;
import javax.persistence.JoinColumn;
import javax.persistence.ManyToMany;
import javax.persistence.ManyToOne;
import javax.persistence.OneToMany;
import javax.persistence.Table;
import javax.persistence.Transient;

import org.hibernate.annotations.Cache;
import org.hibernate.annotations.CacheConcurrencyStrategy;

import com.cj.common.entity.IdEntity;
import com.cj.common.entity.Parent;
import com.cj.common.utils.ReflectionUtils;

/**
 * 受保护的资源.
 * 
 * @author calvin
 */
@Entity
@Table(name = "RESOURCES")
@Cache(usage = CacheConcurrencyStrategy.NONSTRICT_READ_WRITE,region="Resource")
public class Resource extends IdEntity {
	public Resource(Long id) {
		super.setId(id);
	}
	public Resource() {
	}
	
	public static final String QUERY_BY_URL_TYPE = "FROM Resource where resourceType = ? ORDER BY orderNum DESC";
	
	public static final String QUERY_BY_PARENT = "FROM Resource where parent.id = ? and resourceType = ? ORDER BY orderNum ASC";
	// resourceType常量
	public static final String URL_TYPE = "url";
	public static final String MENU_TYPE = "menu";

	private String resourceType; // 资源类型

	private String value; // 资源标识

	private Integer orderNum; // 资源排序字段

	@Parent(textProperty="name")
	private Resource parent; // 父菜单

	private String name; // 资源名称

	private Set<Authority> authorities = new LinkedHashSet<Authority>(); // 可访问该资源的授权

	private Set<Resource> children = new LinkedHashSet<Resource>();; // 子菜单

	@Column(nullable=false)
	public String getResourceType() {
		return resourceType;
	}

	public void setResourceType(String resourceType) {
		this.resourceType = resourceType;
	}

	@Column(nullable=false)
	public String getValue() {
		return value;
	}

	public void setValue(String value) {
		this.value = value;
	}

	public Integer getOrderNum() {
		return orderNum;
	}

	public void setOrderNum(Integer orderNum) {
		this.orderNum = orderNum;
	}

	@Column(nullable=false)
	 public String getName() {
		return name;
	}

	public void setName(String name) {
		this.name = name;
	}

	@ManyToOne(fetch = FetchType.EAGER)
	@JoinColumn(name = "PARENT")
	public Resource getParent() {
		return parent;
	}

	public void setParent(Resource parent) {
		this.parent = parent;
	}

	
	@ManyToMany(mappedBy = "resources")
	public Set<Authority> getAuthorities() {
		return authorities;
	}
	
	@Transient
	@SuppressWarnings("unchecked")
	public List<Long> getAuthIds() throws Exception {
		return ReflectionUtils.fetchElementPropertyToList(authorities, "id");
	}
	
	@OneToMany(mappedBy = "parent")
	public Set<Resource> getChildren() {
		return children;
	}
	
	public void setAuthorities(Set<Authority> authorities) {
		this.authorities = authorities;
	}

	
	 public void setChildren(Set<Resource> children) {
		this.children = children;
	}

	@Transient
	public String getAuthNames() throws Exception {
		return ReflectionUtils.fetchElementPropertyToString(authorities, "name", ",");
	}
}
